package com.bootdo.common.utils;

import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @program: bootdo
 * @packageName: com.bootdo.common.utils
 * @className: PicQrcodeUtil
 * @description: 识别图片中二维码信息
 * @create: 2020-04-18 14:09
 */
public class PicQrcodeUtil {

    private static Logger logger = LoggerFactory.getLogger(PicQrcodeUtil.class);

    /**
     * 解析二维码解析,此方法是解析Base64格式二维码图片
     * baseStr:base64字符串,data:image/png;base64开头的
     */
    public static String deEncodeByBase64(String baseStr) throws Exception {
        String content = null;
        BufferedImage image;
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] b=null;
        try {
            if (baseStr.indexOf("data:image/png;base64")>-1) {
                int i = baseStr.indexOf("data:image/png;base64,");
                baseStr = baseStr.substring(i+"data:image/png;base64,".length());//去掉base64图片的data:image/png;base64,部分才能转换为byte[]
            }

            b = decoder.decodeBuffer(baseStr);//baseStr转byte[]
            ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(b);//byte[] 转BufferedImage
            image = ImageIO.read(byteArrayInputStream);
            LuminanceSource source = new BufferedImageLuminanceSource(image);
            Binarizer binarizer = new HybridBinarizer(source);
            BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
            Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
            hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
            Result result = new MultiFormatReader().decode(binaryBitmap, hints);//解码
            logger.info("图片中内容" + result.getText());
            content = result.getText() + "?t=" + System.currentTimeMillis();
        } catch (IOException e) {
            logger.error("二维码解析失败"+ExceptionUtils.getStackTraceAsString(e));
            e.printStackTrace();
            throw new Exception("二维码解析失败，请重新上传二维码");
        } catch (NotFoundException e) {
            logger.error("二维码解析失败"+ExceptionUtils.getStackTraceAsString(e));
            e.printStackTrace();
            throw new Exception("二维码解析失败，请重新上传二维码");
        }
        return content;
    }
    /**
     * 解析二维码,此方法解析一个路径的二维码图片
     * path:图片路径
     */
    public static String deEncodeByPath(String path) {
        String content = null;
        BufferedImage image;
        try {
            image = ImageIO.read(new File(path));
            LuminanceSource source = new BufferedImageLuminanceSource(image);
            Binarizer binarizer = new HybridBinarizer(source);
            BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
            Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
            hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
            Result result = new MultiFormatReader().decode(binaryBitmap, hints);//解码
            logger.info("图片地址："+path);
            logger.info("识别到的二维码信息：" + result.getText());
            content = result.getText();
            if (content.indexOf("?") > -1){
                content += "&t=" + System.currentTimeMillis() + StringUtils.getUUIDStr(5);
            } else {
                content += "?t=" + System.currentTimeMillis() + StringUtils.getUUIDStr(5);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NotFoundException e) {
            e.printStackTrace();
        }
        return content;
    }

    /**
     * 本地图片转换Base64的方法
     *
     * @param imgPath     
     */

    private static String imageToBase64(String imgPath) {
        byte[] data = null;
        // 读取图片字节数组
        try {
            InputStream in = new FileInputStream(imgPath);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 对字节数组Base64编码
        BASE64Encoder encoder = new BASE64Encoder();
        // 返回Base64编码过的字节数组字符串
        String base64Pic = encoder.encode(Objects.requireNonNull(data));
        System.out.println("本地图片转换Base64:" + base64Pic);
        return base64Pic;
    }

    public static void main(String[] args) {
        System.err.println(deEncodeByPath("D:\\BaiduNetdiskDownload\\1.jpg"));
    }

}
